package com.magnate.software.jdk.action;

import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 基于流的收集器例子
 */
@Slf4j
public class CollectExample {

    static List<Dish> menus = Arrays.asList(
            new Dish("pork", false, 800, Dish.Type.MEAT),
            new Dish("beef", false, 700, Dish.Type.MEAT),
            new Dish("chicken", false, 400, Dish.Type.MEAT),
            new Dish("french fries", true, 530, Dish.Type.OTHER),
            new Dish("rice", true, 350, Dish.Type.OTHER),
            new Dish("season fruit", true, 120, Dish.Type.OTHER),
            new Dish("pizza", true, 550, Dish.Type.OTHER),
            new Dish("prawns", false, 300, Dish.Type.FISH),
            new Dish("salmon", false, 450, Dish.Type.FISH));

    public static void main(String[] args) {
        log.info("collect->Collectors.counting：" + menus.stream().collect(Collectors.counting()));
        log.info("collect->Collectors.summarizingInt：" + menus.stream().collect(Collectors.summarizingInt(Dish::getCalories)));
        log.info("collect->Collectors.summingInt：" + menus.stream().collect(Collectors.summingInt(Dish::getCalories)));
        log.info("collect->Collectors.maxBy：" + menus.stream().collect(Collectors.maxBy(Comparator.comparingInt(Dish::getCalories))));
        log.info("collect->Collectors.minBy：" + menus.stream().collect(Collectors.minBy(Comparator.comparingInt(Dish::getCalories))));
        log.info("collect->Collectors.averagingInt：" + menus.stream().collect(Collectors.averagingInt(Dish::getCalories)));
        log.info("collect->Collectors.averagingInt：" + menus.stream().map(Dish::getName).collect(Collectors.joining(",")));
        log.info("collect->Collectors.reducing：" + menus.stream().collect(Collectors.reducing(0, Dish::getCalories, (i, j) -> i + j)));
        log.info("collect->Collectors.reducing：" + menus.stream().collect(Collectors.reducing((i, j) -> i.getCalories() > j.getCalories() ? i : j)));
        log.info("collect->Collectors.reducing：" + menus.stream().collect(Collectors.reducing(0, Dish::getCalories, Integer::sum)));
        log.info("collect->Collectors.reducing：" + menus.stream().map(item -> 1L).reduce(Long::sum));
        log.info("collect->Collectors.groupingBy：" + menus.stream().collect(Collectors.groupingBy(Dish::getType)));
        log.info("collect->Collectors.groupingBy：" + menus.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.counting())));
        log.info("collect->Collectors.groupingBy：" + menus.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.groupingBy(Dish::isVegetarian))));
        log.info("collect->Collectors.groupingBy：" + menus.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Dish::getCalories)), Optional::get))));
        log.info("collect->Collectors.partitioningBy：" + menus.stream().collect(Collectors.partitioningBy(Dish::isVegetarian, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Dish::getCalories)), Optional::get))));
    }

}
